package com.tbsoft.ehr.action.attendance;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.tbsoft.ehr.action.BaseAction;
import com.tbsoft.ehr.model.Attendance;
import com.tbsoft.ehr.model.AttendanceVo;
import com.tbsoft.ehr.model.ServiceCustomer;
import com.tbsoft.ehr.model.StaffInfo;
import com.tbsoft.ehr.model.YearLeave;
import com.tbsoft.ehr.service.attendance.AttendanceService;
import com.tbsoft.ehr.service.common.WorkdayService;
import com.tbsoft.ehr.service.overtime.OvertimeService;
import com.tbsoft.ehr.service.staffile.StaffFileService;
import com.tbsoft.ehr.util.ConfigProps;

public class AbsenceAction extends BaseAction {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static final Log log = LogFactory.getLog(AbsenceAction.class);
	
	//查询用户信息时存储id
	private String userId;
	private StaffInfo staffInfo;
	//服务客户及其标准工时
	private ServiceCustomer serviceCustomer;
	
	private AttendanceVo attendanceVo;
	private Attendance attendance;
	
	//新增请假信息时使用
	private List<AttendanceVo> attendsVoLst = new ArrayList<AttendanceVo>();	
	//条件查询时使用
	private List<Attendance> attendsLst;
	//查询条件
	private String staffName;
	private String attendMonth;
	//年假信息
	private YearLeave yearLeave;
	//可用调休工时
	private BigDecimal daysOff;
	private StaffFileService staffFileService;
	private WorkdayService workdayService;
	private AttendanceService attendanceService;
	private OvertimeService overtimeService;
	
	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public StaffInfo getStaffInfo() {
		return staffInfo;
	}

	public void setStaffInfo(StaffInfo staffInfo) {
		this.staffInfo = staffInfo;
	}

	public Attendance getAttendance() {
		return attendance;
	}

	public void setAttendance(Attendance attendance) {
		this.attendance = attendance;
	}

	public ServiceCustomer getServiceCustomer() {
		return serviceCustomer;
	}

	public BigDecimal getDaysOff() {
		return daysOff;
	}

	public void setDaysOff(BigDecimal daysOff) {
		this.daysOff = daysOff;
	}

	public void setServiceCustomer(ServiceCustomer serviceCustomer) {
		this.serviceCustomer = serviceCustomer;
	}	

	public YearLeave getYearLeave() {
		return yearLeave;
	}

	public void setYearLeave(YearLeave yearLeave) {
		this.yearLeave = yearLeave;
	}

	public AttendanceVo getAttendanceVo() {
		return attendanceVo;
	}

	public void setAttendanceVo(AttendanceVo attendanceVo) {
		this.attendanceVo = attendanceVo;
	}

	public List<AttendanceVo> getAttendsVoLst() {
		return attendsVoLst;
	}

	public void setAttendsVoLst(List<AttendanceVo> attendsVoLst) {
		this.attendsVoLst = attendsVoLst;
	}

	public List<Attendance> getAttendsLst() {
		return attendsLst;
	}

	public void setAttendsLst(List<Attendance> attendsLst) {
		this.attendsLst = attendsLst;
	}

	public String getStaffName() {
		return staffName;
	}

	public void setStaffName(String staffName) {
		this.staffName = staffName;
	}

	public String getAttendMonth() {
		return attendMonth;
	}

	public void setAttendMonth(String attendMonth) {
		this.attendMonth = attendMonth;
	}

	public void setStaffFileService(StaffFileService staffFileService) {
		this.staffFileService = staffFileService;
	}

	public void setWorkdayService(WorkdayService workdayService) {
		this.workdayService = workdayService;
	}

	public void setAttendanceService(AttendanceService attendanceService) {
		this.attendanceService = attendanceService;
	}

	public void setOvertimeService(OvertimeService overtimeService) {
		this.overtimeService = overtimeService;
	}

	public String queryUser(){
		if(userId!=null&&userId.length()>0){			
			log.info("输入的用户id为："+this.userId);
			staffInfo = this.staffFileService.getStaffFileByUserId(userId);
			if(staffInfo!=null){
				yearLeave = this.attendanceService.queryYearLeaveByUserId(userId).get(0);
				BigDecimal overtime = this.overtimeService.getOvertimesByStaffId(staffInfo.getStaffId());				
				BigDecimal dayoff = this.attendanceService.getDaysOffByStaffId(staffInfo.getStaffId());
				daysOff = overtime.subtract(dayoff);
			}
		}
		return "queryUser";		
	}
	
	public String save() {						
		if(staffInfo.getUserId().isEmpty()||staffInfo.getSex().isEmpty()) {
			return errorReturn("用户信息不完整，请检查");
		}
		//判断服务客户工时是否已设置
		if(!serviceCustomer.getId().isEmpty()&&serviceCustomer.getWorkingHour()==null) {
			return errorReturn("服务客户的工时没有设置，请检查");
		}				
		
		Set<Attendance> attendanceSet = new HashSet<Attendance>();
		
		//按有多条请假信息进行处理
		attendsVoLst.add(attendanceVo);
		for(AttendanceVo ad:attendsVoLst){
			List<Date> adDateLst = new ArrayList<Date>();
			//缺勤时间
			BigDecimal absenceTime = null;
			if(ad.getEndDate()!=null) {
				//获取该工作区间的工作日
				adDateLst = workdayService.getWorkDays(ad.getStartDate(), ad.getEndDate(), staffInfo.getSex());
				absenceTime = serviceCustomer.getWorkingHour();
			} else {
				//判断单日请假是否为工作日
				if(workdayService.isWorkDay(ad.getStartDate(), staffInfo.getSex())){				
					adDateLst.add(ad.getStartDate());
					absenceTime = new BigDecimal(ad.getHours());
				} 
			}
			for(Date d:adDateLst) {
				Attendance a = new Attendance();
				a.setAdDate(d);
				a.setAdType(ad.getAdType());
				a.setHours(absenceTime);
				a.setRemark(ad.getRemark());
				a.setStaff(staffInfo);
				a.setServiceCustomer(serviceCustomer);
				if(!attendanceSet.add(a)){
					return errorReturn("请不要在同一日期添加多条请假信息");
				}
			}
		}	
		//判断所休年假数,调休假
		int yearLeaveDay = 0;
		String njId = (String)ConfigProps.getContextProperty("ehr.public.attend.yearLeave");
		BigDecimal dayoff = new BigDecimal("0");
		String txjId = (String)ConfigProps.getContextProperty("ehr.public.attend.daysOff");
		for(Attendance ad:attendanceSet) {
			if(njId.equals(ad.getAdType())){				
				yearLeaveDay+=1;
			} 
			if(txjId.equals(ad.getAdType())) {
				dayoff=dayoff.add(ad.getHours());
			}
		}
		if(yearLeaveDay>yearLeave.getUnusedDay()) {
			return errorReturn("您所休的年假天数已经超过可休天数："+yearLeave.getUnusedDay()+"天");
		}
		if(dayoff.compareTo(daysOff)>0) {
			return errorReturn("您所休的调休假总工时已经超过可休工时："+daysOff);
		}
		
		StringBuilder sb = new StringBuilder();
		SimpleDateFormat sdf = new SimpleDateFormat("yy-M-d");
		List<Attendance> attendanceLst = new ArrayList<Attendance>();
		//判断是否在一天添加了多条请假
		for(Attendance ad:attendanceSet) {
			if(attendanceService.hasAbsenceInDate(ad.getStaff().getUserId(), ad.getAdDate())){
				sb.append(sdf.format(ad.getAdDate())).append(",");
			} else{
				attendanceLst.add(ad);
			}
		}			
		if(!sb.toString().isEmpty()) {
			return errorReturn(sb.substring(0, sb.length()-1)+":已存在请假信息，操作失败");
		}
		
		log.info("将要保存请假信息条数为："+attendanceLst.size());
		if(attendanceLst.size()>0) {			
			try {			
				attendanceService.addAttendances(attendanceLst);	
				setRel("attendance_browse");
				return SUCCESS;
			} catch(Exception ex){
				log.error("保存请假数据失败:",ex);
				return errorReturn("保存请假数据失败："+ex.getMessage());
			}
		}				
		return errorReturn("没有需要保存的请假数据");
	}
	
	public String query(){
		int pageNum = this.getPageNum() > 0 ? this.getPageNum() - 1 : 0;
		int startIndex = pageNum * getNumPerPage();		
				
		String adTimeFromStr=null;
		String adTimeToStr = null;
		if(this.attendMonth!=null && !this.attendMonth.isEmpty()) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Calendar calendar = Calendar.getInstance();
			calendar.set(Calendar.MONTH, Integer.parseInt(this.attendMonth)-1);
			calendar.set(Calendar.DAY_OF_MONTH, 1);
			adTimeFromStr = sdf.format(calendar.getTime());
			calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
			adTimeToStr = sdf.format(calendar.getTime());
		}						
		
		int count = this.attendanceService.getAbsenceCount(staffName, adTimeFromStr, adTimeToStr);
		log.info("该条件下获得数据总条数为："+count);
		setTotalCount(count);
		setPageNumShown((getNumPerPage()+count)/getNumPerPage());
		attendsLst = attendanceService.getAbsenceByCondton(staffName, adTimeFromStr, adTimeToStr, startIndex, getNumPerPage());
		return "browse";
	}
	
	public String edit() {
		if(!attendanceVo.getId().isEmpty()) {
			attendance = attendanceService.getAttendanceById(attendanceVo.getId());
			return "update";
		}
		return "browse";
	}
	
	public String update(){
		attendance.setId(Integer.parseInt(attendanceVo.getId()));
		attendance.setHours(new BigDecimal(attendanceVo.getHours()));		
		attendanceService.updateAbsence(attendance);
		setRel("attendance_browse");
		return SUCCESS;
	}
	
	public String delete(){
		attendance.setId(Integer.parseInt(attendanceVo.getId()));
		attendanceService.deleteAbsence(attendance);
		setRel("attendance_browse");
		return SUCCESS;
	}
}
